package model;

import org.jblas.DoubleMatrix;

import util.Params;

/**
 * The non-linear layer of the network.
 * 
 * 神经网络的非线性函数层。
 * 
 * @author Tianyu
 * 
 */
public class NonlinearLayer {
	/**
	 * 硬性双曲正切函数
	 * 
	 * @param input
	 *            输入的 double 值
	 * @return 经过硬性双曲正切变换后的 double 值
	 */
	public static double hardTanh(double input) {
		if (input < -1)
			return -1;
		if (input > 1)
			return 1;
		return input;
	}

	/**
	 * Sigmoid 函数
	 * 
	 * @param input
	 *            输入的 double 值
	 * @return 经过 sigmoid 函数变换后的 double 值
	 */
	public static double sigmoid(double input) {
		return 1.0 / (1 + Math.exp(-input));
	}

	/**
	 * 对输入矩阵进行非线性变换
	 * 
	 * @param input
	 *            要进行非线性变换的输入矩阵
	 * @return 进行非线性变换后的输出矩阵
	 */
	@SuppressWarnings("unused")
	public DoubleMatrix performNonlinearTrans(DoubleMatrix input) {
		int row = input.rows;
		int col = input.columns;
		DoubleMatrix output = new DoubleMatrix(row, col);

		for (int r = 0; r < row; r++) {
			for (int c = 0; c < col; c++) {
				if (Params.NONLINEAR_FUNC_TYPE == Params.SIGMOID)
					output.put(r, c, sigmoid(input.get(r, c)));
				else if (Params.NONLINEAR_FUNC_TYPE == Params.HARD_TANH)
					output.put(r, c, hardTanh(input.get(r, c)));
			}
		}
		return output;
	}
}
